'''
    作者：刘妍
    日期：2021/11/19
    版本：1.0
    功能：设计一个小球撞墙（窗口模拟）或挡板回弹的动画程序
    需求分析：
    1 小球类   画布，挡板，小球的颜色
        画小球回弹的运动
    2 挡板类   画布，挡板的颜色
        画挡板左右移动的运动
        挡板的左右移动由键盘触发
'''

# 和窗口设计相关的类
from tkinter import *
import random
import time

# 定义类
class Ball:
    # 构造方法 完成类的初始化设置
    def __init__(self, canvas, paddle, color):
        self.canvas = canvas
        self.paddle = paddle
        # 画好了涂色成功的小球，self.id
        self.id = self.canvas.create_oval\
            (10, 10, 35, 35, fill=color)
        self.canvas.move(self.id, 245, 100)

        start = [-3, -2, -1, 1, 2, 3]
        # shuffle(start)随机列表
        random.shuffle(start)
        self.x = start[0]
        self.y = -3

        # 获取小球的运动区域
        self.canvas_width = \
            self.canvas.winfo_width()
        self.canvas_height = \
            self.canvas.winfo_height()

    def draw_ball(self):
        """
        功能：实现小球回弹的操作
        :return:
        """
        self.canvas.move(self.id, self.x, self.y)
        # coords()获取对象的左上角和右上角坐标
        pos = self.canvas.coords(self.id)
        pad = self.canvas.coords(self.paddle.id)
        if pos[0] <= 0:
            self.x = 3
        if pos[2] >= self.canvas_width:
            self.x = -3
        if pos[1] <= 0:
            self.y = 3
        if pos[2]>=pad[0] and pos[0]<=pad[2]: #y
            if pad[1]<pos[3]<pad[3]: #x
                self.y=-3
        if pos[3] >= self.canvas_height:
            exit(print("游戏结束"))

class Paddle:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = self.canvas.\
        create_rectangle(0, 0, 100, 10, fill=color)
        self.canvas.move(self.id, 200, 300)
        # 获取窗口的宽度
        self.canvas_width = \
            self.canvas.winfo_width()
        self.l = 0
        self.r = 0

    # 画挡板左右移动的过程
    def draw_paddle(self):
        pos = self.canvas.coords(self.id)
        if pos[0] <= 0:
            self.l = 0
        if pos[2] >= self.canvas_width:
            self.r = 0

    # 设计两个键盘触发事件
    def turn_left(self, event):
        # move(对象, 水平偏移量, 垂直偏移量)
        self.canvas.move(self.id, self.l, 0)
        self.l = -20

    def turn_right(self, event):
        self.canvas.move(self.id, self.r, 0)
        self.r = 20

def main():
    # 类的实例化
    tk = Tk()
    tk.title('Ball Game')
    # 设置窗口的大小不可改变
    tk.resizable(0, 0)
    # 设置当前窗口总在最前端显示，即置顶功能
    tk.wm_attributes('-topmost', 1)
    # 设置画布的大小，后两个参数为不加边框
    canvas = Canvas(tk, width=500, height=400,
        bd=0, highlightthickness=0)
    canvas.pack()
    tk.update()

    paddle = Paddle(canvas, 'blue')
    ball = Ball(canvas, paddle, 'red')

    # 绑定方向键
    canvas.bind_all('<KeyPress-Left>',
                    paddle.turn_left)
    canvas.bind_all('<KeyPress-Right>',
                    paddle.turn_right)

    # 小球一直运动
    while True:
        ball.draw_ball()
        paddle.draw_paddle()
        # 快速重画屏幕
        tk.update_idletasks()
        tk.update()
        time.sleep(0.01)




if __name__ == '__main__':
    main()

